# coding = utf-8

'''
基于现有数据计算dice的结果
'''

import cv2,os
import numpy as np
import matplotlib.pyplot as plt
import SimpleITK as sitk
from PIL import Image
import math
from scipy import ndimage
from skimage import measure

def liver_index_2_all_index(case_id, origion_id, index):
    big_liver = "E:\Dataset\Liver\qiye\DongBeiDaXue2\liver\\data2_{}_liver_label.mha".format(origion_id)

    big_liver = sitk.GetArrayFromImage(sitk.ReadImage(big_liver))

    for i in range(big_liver.shape[0]):
        if index == 0:
            return i
        if big_liver[i].sum() > 0 :
            index -= 1

def calcuate_dice(case_id, origion_id):
    big_image = "E:\Dataset\Liver\qiye\DongBeiDaXue2\image_venous\\data2_{}_venous.mha".format(origion_id)
    big_liver = "E:\Dataset\Liver\qiye\DongBeiDaXue2\liver\\data2_{}_liver_label.mha".format(origion_id)
    big_tumor = "E:\Dataset\Liver\qiye\DongBeiDaXue2\lesion\\data2_{}_lesion_label.mha".format(origion_id)
    predict_tumor = "E:\predict\image_tumor_v3\case_{}\predict_tumor".format(str(case_id).zfill(5))

    mask = sitk.GetArrayFromImage(sitk.ReadImage(big_tumor))
    mask[mask>0] = 1
    predict = np.zeros(mask.shape)

    for item in sorted(os.listdir(predict_tumor)):
        index = int(item.split(".")[0])
        index = liver_index_2_all_index(case_id=case_id, origion_id=origion_id, index=index)
        file_name = os.path.join(predict_tumor, item)
        data = Image.open(file_name).convert("L")
        data = np.array(data)
        data[data>0] = 1
        predict[index] = data

    dice = 2 * (predict*mask).sum() / (predict.sum() + mask.sum())
    print(dice)

def calcuate_dice_after_gabor(case_id, origion_id):
    def garbor_filter4(image):
        image = image * 255
        image = image.astype(np.uint8)

        temp = np.zeros(image.shape)

        filters3 = []
        # theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        for item in theta2:
            kern = cv2.getGaborKernel((2, 2), sigma=1.0, theta=item, lambd=np.pi / 2.0, gamma=0.5, psi=0,
                                      ktype=cv2.CV_32F)
            # kern = cv2.getGaborKernel((10, 10), sigma=1.0, theta=item, lambd=5, gamma=0.5, psi=0, ktype=cv2.CV_32F)
            kern /= 1.5 * kern.sum()
            filters3.append(kern)
        result3 = np.zeros_like(temp)
        for i in range(len(filters3)):
            accum = np.zeros_like(image)
            for kern in filters3[i]:
                fimg = cv2.filter2D(image, cv2.CV_8UC1, kern)
                accum = np.maximum(accum, fimg, accum)
            result3 += np.array(accum)
        result3 = result3 / len(filters3)
        result3 = result3.astype(np.uint8)
        # clahe = cv2.createCLAHE(clipLimit=5, tileGridSize=(100, 100))
        result3 = cv2.equalizeHist(result3)
        # result3 = clahe.apply(result3)

        return result3

    big_image = "E:\Dataset\Liver\qiye\DongBeiDaXue2\image_venous\\data2_{}_venous.mha".format(origion_id)
    big_liver = "E:\Dataset\Liver\qiye\DongBeiDaXue2\liver\\data2_{}_liver_label.mha".format(origion_id)
    big_tumor = "E:\Dataset\Liver\qiye\DongBeiDaXue2\lesion\\data2_{}_lesion_label.mha".format(origion_id)
    predict_tumor = "E:\predict\image_tumor_v3\case_{}\predict_tumor".format(str(case_id).zfill(5))


    big_image = sitk.GetArrayFromImage(sitk.ReadImage(big_image))
    big_image[big_image <= -200] = -200
    big_image[big_image > 250] = 250
    big_image = (big_image + 200) / 450

    big_liver = sitk.GetArrayFromImage(sitk.ReadImage(big_liver))
    big_liver[big_liver>0] = 1

    mask = sitk.GetArrayFromImage(sitk.ReadImage(big_tumor))
    mask[mask > 0] = 1
    predict = np.zeros(mask.shape)

    for item in sorted(os.listdir(predict_tumor)):
        index = int(item.split(".")[0])
        index = liver_index_2_all_index(case_id=case_id, origion_id=origion_id, index=index)

        image = big_image[index] * big_liver[index]
        garbor_result = garbor_filter4(image)
        garbor_result = cv2.medianBlur((255 - garbor_result) * big_liver[index], ksize=5)
        garbor_result[garbor_result <= 200] = 0
        garbor_result[garbor_result > 200] = 1

        file_name = os.path.join(predict_tumor, item)
        data = Image.open(file_name).convert("L")
        data = np.array(data)
        data[data > 0] = 1
        data = data * garbor_result
        predict[index] = data





    dice = 2 * (predict * mask).sum() / (predict.sum() + mask.sum())
    print(dice)

#新提出的方法
def calcuate_dice_after_gabor_v2(case_id, origion_id):
    def garbor_filter4(image):
        image = image * 255
        image = image.astype(np.uint8)

        temp = np.zeros(image.shape)

        filters3 = []
        # theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        for item in theta2:
            kern = cv2.getGaborKernel((2, 2), sigma=1.0, theta=item, lambd=np.pi / 2.0, gamma=0.5, psi=0,
                                      ktype=cv2.CV_32F)
            # kern = cv2.getGaborKernel((10, 10), sigma=1.0, theta=item, lambd=5, gamma=0.5, psi=0, ktype=cv2.CV_32F)
            kern /= 1.5 * kern.sum()
            filters3.append(kern)
        result3 = np.zeros_like(temp)
        for i in range(len(filters3)):
            accum = np.zeros_like(image)
            for kern in filters3[i]:
                fimg = cv2.filter2D(image, cv2.CV_8UC1, kern)
                accum = np.maximum(accum, fimg, accum)
            result3 += np.array(accum)
        result3 = result3 / len(filters3)
        result3 = result3.astype(np.uint8)
        # clahe = cv2.createCLAHE(clipLimit=5, tileGridSize=(100, 100))
        result3 = cv2.equalizeHist(result3)
        # result3 = clahe.apply(result3)

        return result3

    big_image = "E:\Dataset\Liver\qiye\DongBeiDaXue2\image_venous\\data2_{}_venous.mha".format(origion_id)
    big_liver = "E:\Dataset\Liver\qiye\DongBeiDaXue2\liver\\data2_{}_liver_label.mha".format(origion_id)
    big_tumor = "E:\Dataset\Liver\qiye\DongBeiDaXue2\lesion\\data2_{}_lesion_label.mha".format(origion_id)
    predict_tumor = "E:\predict\image_tumor_v3\case_{}\predict_tumor".format(str(case_id).zfill(5))


    big_image = sitk.GetArrayFromImage(sitk.ReadImage(big_image))
    big_image[big_image <= -200] = -200
    big_image[big_image > 250] = 250
    big_image = (big_image + 200) / 450

    big_liver = sitk.GetArrayFromImage(sitk.ReadImage(big_liver))
    big_liver[big_liver>0] = 1

    mask = sitk.GetArrayFromImage(sitk.ReadImage(big_tumor))
    mask[mask > 0] = 1
    predict = np.zeros(mask.shape)

    for item in sorted(os.listdir(predict_tumor)):
        index = int(item.split(".")[0])
        index = liver_index_2_all_index(case_id=case_id, origion_id=origion_id, index=index)

        image = big_image[index] * big_liver[index]
        garbor_result = garbor_filter4(image)
        garbor_result = cv2.medianBlur((255 - garbor_result) * big_liver[index], ksize=5)
        garbor_result[garbor_result <= 200] = 0
        garbor_result[garbor_result > 200] = 1



        file_name = os.path.join(predict_tumor, item)
        data = Image.open(file_name).convert("L")
        data = np.array(data)
        data[data > 0] = 1
        data = data * garbor_result

        [after_labels, num_after] = measure.label(data, return_num=True)
        for i in range(num_after):
            if (after_labels==i+1).sum() < 20:
                data[after_labels == i+1] = 0

        predict[index] = data





    dice = 2 * (predict * mask).sum() / (predict.sum() + mask.sum())
    print(dice)

def calcuate_dice_after_gabor_each_dice(case_id, origion_id):
    def garbor_filter4(image):
        image = image * 255
        image = image.astype(np.uint8)

        temp = np.zeros(image.shape)

        filters3 = []
        # theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        for item in theta2:
            kern = cv2.getGaborKernel((2, 2), sigma=1.0, theta=item, lambd=np.pi / 2.0, gamma=0.5, psi=0,
                                      ktype=cv2.CV_32F)
            # kern = cv2.getGaborKernel((10, 10), sigma=1.0, theta=item, lambd=5, gamma=0.5, psi=0, ktype=cv2.CV_32F)
            kern /= 1.5 * kern.sum()
            filters3.append(kern)
        result3 = np.zeros_like(temp)
        for i in range(len(filters3)):
            accum = np.zeros_like(image)
            for kern in filters3[i]:
                fimg = cv2.filter2D(image, cv2.CV_8UC1, kern)
                accum = np.maximum(accum, fimg, accum)
            result3 += np.array(accum)
        result3 = result3 / len(filters3)
        result3 = result3.astype(np.uint8)
        # clahe = cv2.createCLAHE(clipLimit=5, tileGridSize=(100, 100))
        result3 = cv2.equalizeHist(result3)
        # result3 = clahe.apply(result3)

        return result3

    big_image = "E:\Dataset\Liver\qiye\DongBeiDaXue2\image_venous\\data2_{}_venous.mha".format(origion_id)
    big_liver = "E:\Dataset\Liver\qiye\DongBeiDaXue2\liver\\data2_{}_liver_label.mha".format(origion_id)
    big_tumor = "E:\Dataset\Liver\qiye\DongBeiDaXue2\lesion\\data2_{}_lesion_label.mha".format(origion_id)
    predict_tumor = "E:\predict\image_tumor_v3\case_{}\predict_tumor".format(str(case_id).zfill(5))

    big_image = sitk.GetArrayFromImage(sitk.ReadImage(big_image))
    big_image[big_image <= -200] = -200
    big_image[big_image > 250] = 250
    big_image = (big_image + 200) / 450

    big_liver = sitk.GetArrayFromImage(sitk.ReadImage(big_liver))
    big_liver[big_liver > 0] = 1

    mask = sitk.GetArrayFromImage(sitk.ReadImage(big_tumor))
    mask[mask > 0] = 1


    for item in sorted(os.listdir(predict_tumor)):
        index_old = int(item.split(".")[0])
        index = liver_index_2_all_index(case_id=case_id, origion_id=origion_id, index=index_old)

        file_name = os.path.join(predict_tumor, item)
        data = Image.open(file_name).convert("L")
        data = np.array(data)
        data[data > 0] = 1

        before_dice = (2 * (data*mask[index]).sum() + 1) / (data.sum() + mask[index].sum() + 1)
        before_sum = data.sum()

        image = big_image[index] * big_liver[index]
        garbor_result = garbor_filter4(image)
        garbor_result = cv2.medianBlur((255 - garbor_result) * big_liver[index], ksize=5)
        garbor_result[garbor_result <= 150] = 0
        garbor_result[garbor_result > 150] = 1


        data = data * garbor_result
        after_dice = (2 * (data * mask[index]).sum() + 0.001) / (data.sum() + mask[index].sum() + 0.001)

        print(index_old, index, "%.3f" % before_dice, "%.3f" % after_dice, before_sum, data.sum(), mask[index].sum())

def gabor_dice_show(case_id, origion_id, image_index):
    def garbor_filter4(image):
        image = image * 255
        image = image.astype(np.uint8)

        temp = np.zeros(image.shape)

        filters3 = []
        # theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        theta2 = [0, 1 * np.pi / 6, 2 * np.pi / 6, 3 * np.pi / 6, 4 * np.pi / 6, 5 * np.pi / 6]
        for item in theta2:
            kern = cv2.getGaborKernel((2, 2), sigma=1.0, theta=item, lambd=np.pi / 2.0, gamma=0.5, psi=0,
                                      ktype=cv2.CV_32F)
            # kern = cv2.getGaborKernel((10, 10), sigma=1.0, theta=item, lambd=5, gamma=0.5, psi=0, ktype=cv2.CV_32F)
            kern /= 1.5 * kern.sum()
            filters3.append(kern)
        result3 = np.zeros_like(temp)
        for i in range(len(filters3)):
            accum = np.zeros_like(image)
            for kern in filters3[i]:
                fimg = cv2.filter2D(image, cv2.CV_8UC1, kern)
                accum = np.maximum(accum, fimg, accum)
            result3 += np.array(accum)
        result3 = result3 / len(filters3)
        result3 = result3.astype(np.uint8)
        # clahe = cv2.createCLAHE(clipLimit=5, tileGridSize=(100, 100))
        result3 = cv2.equalizeHist(result3)
        # result3 = clahe.apply(result3)

        return result3

    big_image = "E:\Dataset\Liver\qiye\DongBeiDaXue2\image_venous\\data2_{}_venous.mha".format(origion_id)
    big_liver = "E:\Dataset\Liver\qiye\DongBeiDaXue2\liver\\data2_{}_liver_label.mha".format(origion_id)
    big_tumor = "E:\Dataset\Liver\qiye\DongBeiDaXue2\lesion\\data2_{}_lesion_label.mha".format(origion_id)
    predict_tumor = "E:\predict\image_tumor_v3\case_{}\predict_tumor".format(str(case_id).zfill(5))

    big_image = sitk.GetArrayFromImage(sitk.ReadImage(big_image))
    big_image[big_image <= -200] = -200
    big_image[big_image > 250] = 250
    big_image = (big_image + 200) / 450

    big_liver = sitk.GetArrayFromImage(sitk.ReadImage(big_liver))
    big_liver[big_liver > 0] = 1

    mask = sitk.GetArrayFromImage(sitk.ReadImage(big_tumor))
    mask[mask > 0] = 1


    for item in sorted(os.listdir(predict_tumor)):
        index_old = int(item.split(".")[0])
        index = liver_index_2_all_index(case_id=case_id, origion_id=origion_id, index=index_old)
        if index != image_index:
            continue



        file_name = os.path.join(predict_tumor, item)
        data = Image.open(file_name).convert("L")
        data = np.array(data)
        data[data > 0] = 1

        plt.subplot(1, 3, 2)
        plt.title("predict")
        plt.imshow(data, cmap="gray")

        image = big_image[index] * big_liver[index]
        garbor_result = garbor_filter4(image)
        garbor_result = cv2.medianBlur((255 - garbor_result) * big_liver[index], ksize=5)
        garbor_result[garbor_result <= 150] = 0
        garbor_result[garbor_result > 150] = 1
        data = data * garbor_result

        big_tumor = mask[index]
        big_tumor[big_tumor > 0] = 1
        big_tumor = big_tumor * 255
        big_tumor = big_tumor.astype(np.uint8)
        contours, _ = cv2.findContours(big_tumor, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        liver_t = np.zeros(data.shape)
        temp = big_image[index] * big_liver[index]
        liver_t += (temp * garbor_result)
        liver_t += (temp * (1 - garbor_result) * 1.2)
        liver_t = liver_t / 1.2
        liver_t = liver_t * 255
        liver_t = liver_t.astype(np.uint8)
        liver_t = cv2.cvtColor(liver_t, cv2.COLOR_GRAY2BGR)
        for counter in contours:
            data_list = []
            for t in range(counter.shape[0]):
                j = counter[t][0]
                data_list.append(j)
            cv2.polylines(liver_t, np.array([data_list], np.int32), True, [0, 255, 0], thickness=1)




        plt.subplot(1, 3, 1)
        plt.title("origion")
        plt.imshow(image, cmap="gray")
        #plt.subplot(2, 3, 2)
        #plt.imshow(liver_t)
        plt.subplot(1, 3, 3)
        plt.title("after processing")
        plt.imshow(data, cmap="gray")
        #plt.subplot(2, 3, 6)
        #plt.imshow(garbor_result, cmap="gray")
        plt.show()








if __name__ == '__main__':
    #calcuate_dice(case_id="78", origion_id="0767")
    #calcuate_dice_after_gabor(case_id="78", origion_id="0767")
    #calcuate_dice_after_gabor_v2(case_id="78", origion_id="0865")
    #calcuate_dice_after_gabor_each_dice(case_id="72", origion_id="0628")
    gabor_dice_show(case_id="77", origion_id="0762", image_index=177)


